/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-09-25     huger       the first version
 */

#include "bsp_i2c.h"
#include <stdlib.h>

#define DBG_TAG "i2c"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
static rt_bool_t initialized = RT_FALSE;

static rt_err_t write_reg(rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
{
    struct rt_i2c_msg msgs[2];
    //设备地址 -- 寄存器号
    msgs[0].addr = AW20036_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = &reg;
    msgs[0].len = 1;
    //打算往寄存器里写什么
    msgs[1].addr = AW20036_ADDR;
    msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
    msgs[1].buf = buf;
    msgs[1].len = len;

    if(rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
    {
        return RT_EOK;
    }
    else{
        LOG_E("Writing Command Error.");
        return RT_ERROR;
    }
}

static rt_err_t read_reg(rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
{
    struct rt_i2c_msg msgs[2];

    msgs[0].addr = AW20036_ADDR;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = &reg;
    msgs[0].len = 1;

    msgs[1].addr = AW20036_ADDR;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf = buf;
    msgs[1].len = len;

    if(rt_i2c_transfer(i2c_bus, msgs, 2) == 2)
    {
        return RT_EOK;
    }
    else{
        LOG_E("Reading command error.");
        return -RT_ERROR;
    }
}


void bsp_i2c_init(void)
{
    uint8_t value=0;
    /* 查找I2C总线设备，获取I2C总线设备句柄 */
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(AW20036_I2C_BUS_NAME);

    if (i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s device!\n", AW20036_I2C_BUS_NAME);
    }
    else
    {
        initialized = RT_TRUE;
    }

    rt_pin_mode(HWEN_PIN, PIN_MODE_OUTPUT);
//    rt_pin_mode(INTN_PIN, PIN_MODE_OUTPUT_OD);

    rt_pin_write(HWEN_PIN, 1);  //hardware ctr enable
//    rt_pin_write(INTN_PIN, 0);  //Interrupt output, open drain output, low active

    value = 0xc0;
    write_reg(page_change_reg,1,&value);
    value = 0x01;
    write_reg(soft_reset_reg,1,&value);
}


/*
亮灯需要配置Imax（page0下的0x03寄存器，如配置0x18) && DIM（page1） && FADE（page2 or page3）。
例如LED常亮的基本寄存器配置方法：
0xF0, 0xC0,  //切换到page0
0x02, 0x01,  //软复位
//延时2ms
0x03, 0x18,  //配置Imax电流，ALLON bit to 1
0x80, 0x02,  //配置SIZE，C1/C2/C3
0x01, 0x00,  //芯片配置到active模式
0xF0, 0xC1,  //切换到page1
0x00+i, 0x3f, //DIM: 将0x00~0x23寄存器配置为0x3f
0xF0, 0xC2,   //切换到page2
0x00+i, 0xff,  //FADE: 将0x00~0x23寄存器配置为0xff
*/


void auto_breth_light(void)
{
    uint8_t reg,value;

    uint8_t led_state[36]={0};

    value = 0xC0;write_reg(page_change_reg,1,&value);
    value = 0x00;write_reg(mode_control_reg,1,&value);
    value = 0xC1;write_reg(page_change_reg,1,&value);
    value = 0x3f;for(uint8_t i =0 ;i<36;i++)write_reg(i,1,&value);
    value = 0xC2;write_reg(page_change_reg,1,&value);
    value = 0xff;for(uint8_t i =0 ;i<36;i++)write_reg(i,1,&value);
    value = 0xC3;write_reg(page_change_reg,1,&value);
    value = 0x03;for(uint8_t i =0 ;i<36;i++)write_reg(i,1,&value);

    value = 0xC0;write_reg(page_change_reg,1,&value);

    value = 0x1f;write_reg(0x44,1,&value);
    value = 0x1f;write_reg(0x45,1,&value);
    value = 0x1f;write_reg(0x46,1,&value);
    value = 0x00;write_reg(0x47,1,&value);
    value = 0x00;write_reg(0x48,1,&value);
    value = 0x00;write_reg(0x49,1,&value);

    value = 0x22;write_reg(0x4a,1,&value);
    value = 0x44;write_reg(0x4e,1,&value);
    value = 0x66;write_reg(0x52,1,&value);
    value = 0x22;write_reg(0x4b,1,&value);
    value = 0x44;write_reg(0x4f,1,&value);
    value = 0x66;write_reg(0x53,1,&value);

    value = 0x01;write_reg(0x56,1,&value);
    value = 0x01;write_reg(0x57,1,&value);
    value = 0x01;write_reg(0x58,1,&value);

    value = 0x30;write_reg(0x4c,1,&value);
    value = 0x30;write_reg(0x50,1,&value);
    value = 0x30;write_reg(0x54,1,&value);
    value = 0x00;write_reg(0x4d,1,&value);
    value = 0x00;write_reg(0x51,1,&value);
    value = 0x00;write_reg(0x55,1,&value);

    value = 0x77;write_reg(0x43,1,&value);

    value = 0x07;for(uint8_t i =0 ;i<5; i=i+2)write_reg(0x31+i,1,&value);

    value = 0x07;write_reg(0x59,1,&value);
    value = 0x00;write_reg(0x59,1,&value);
}


static int i2c_test_info(int argc, char *argv[])
{
    auto_breth_light();
    return RT_EOK;
}
MSH_CMD_EXPORT(i2c_test_info, i2c读写测试);
